package cn.gzmli.dtt.common.workflow.controller;

import cn.gzmli.dtt.common.annotation.Comment;
import cn.gzmli.dtt.common.annotation.Ignore;
import cn.gzmli.dtt.common.config.cache.Config;
import cn.gzmli.dtt.common.entity.Department;
import cn.gzmli.dtt.common.entity.PageInfo;
import cn.gzmli.dtt.common.entity.Result;
import cn.gzmli.dtt.common.entity.User;
import cn.gzmli.dtt.common.service.DepartmentService;
import cn.gzmli.dtt.common.service.UserService;
import cn.gzmli.dtt.common.utils.BaseUtil;
import cn.gzmli.dtt.common.utils.ComMapObjCompatator;
import cn.gzmli.dtt.common.utils.Constant;
import cn.gzmli.dtt.common.workflow.controller.constant.WorkFlowEnum;
import cn.gzmli.dtt.common.workflow.controller.vo.WorkFlow_VO;
import cn.gzmli.dtt.common.workflow.dao.WorkFlowDao;
import cn.gzmli.dtt.common.workflow.entity.TaskLog;
import cn.gzmli.dtt.common.workflow.entity.WorkFlow;
import cn.gzmli.dtt.common.workflow.service.FlowNodeService;
import cn.gzmli.dtt.common.workflow.service.TaskLogService;
import cn.gzmli.dtt.common.workflow.service.WorkFlowService;
import com.alibaba.druid.support.logging.Log;
import com.alibaba.druid.support.logging.LogFactory;
import com.xiaoleilu.hutool.lang.Base64;
import net.sf.json.JSONObject;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Property;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.*;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

/**
 * 工作流业务相关
 * @author wonderful
 * @create 20160117
 */
@Controller
@RequestMapping({"/workFlow","/app/workFlow"})
@Ignore
public class WorkFlowController {

	private Log logger = LogFactory.getLog(getClass());

	@Autowired
	private WorkFlowService workFlowService;

	@Autowired
	private WorkFlowDao workFlowDao;
	
	@Autowired
	private UserService userService;

	@Autowired
	private TaskLogService taskLogService;

	@Autowired
	private FlowNodeService flowNodeService;
	
	@Autowired
	private DepartmentService departmentService;

	@RequestMapping("/workFlowView.view")
	public void workFlowView(HttpServletRequest request,HttpServletResponse response){
		try {
			request.setAttribute("session",request.getSession());
			request.getRequestDispatcher("/dtt/main?url=/imp/workFlow/workFlowView").forward(request,response);
		} catch (ServletException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	@RequestMapping(value = "/changeOrAddFlow.wdf")
	@ResponseBody
	public Map<String, Object> changeOrAddFlow(HttpServletRequest request,
                                               HttpServletResponse response,
                                               String workFlowStr,
                                               String removeNodeOrders,
                                               String removeNodeIDS,
                                               String workFlowId)
			throws Exception {

		Map<String, Object> result = new HashMap<String, Object>();
		WorkFlow_VO workFlow =null;
		JSONObject jsonObj = JSONObject.fromObject(workFlowStr);
		workFlow=(WorkFlow_VO) JSONObject.toBean(jsonObj,WorkFlow_VO.class);
		if(workFlow.getId()==null||workFlow.getId().equals("")){
			result.put("state",0);
			result.put("msg","流程ID不能为空");
		}else{
			//workFlow.setFlowViewData(Base64.encode(workFlow.getFlowViewData().getBytes()));
			workFlowService.updateOrInsertWorkFlow(workFlowId,workFlow, removeNodeIDS);
			result.put("state",1);
			result.put("msg","执行成功！");
		}
		return result;

	}

	//根据条件列表流程信息
	@RequestMapping(value="/listWorkFlows.wdf")
	@ResponseBody
	public Map<String,Object> listWorkFlows(HttpServletRequest request,
											HttpServletResponse response, PageInfo pageInfo, String workFlowID, String workFlowName)throws Exception {
		Map<String,Object> result=new HashMap<String,Object>();
		Map<String,String> condition=new HashMap<String,String>();
		if(workFlowID!=null&&!workFlowID.equals("")){
			condition.put("id"," ='"+workFlowID+"'");
		}
		result.put("workFlows",workFlowService.queryWorkFlow(condition, pageInfo));
		result.put("pageInfo",pageInfo);
		result.put("status", Constant.SUCCESS);
		return result;
	}

	//根据流程ID获取流程信息
	@RequestMapping(value="/getWorkFlowByID.wdf")
	@ResponseBody
	public Map<String,Object> getWorkFlowByID(HttpServletRequest request,
                                              HttpServletResponse response, PageInfo pageInfo, String workFlowID)throws Exception {
		Map<String,Object> result=new HashMap<String,Object>();
		WorkFlow workFlow=workFlowService.queryWorkFlowByID(workFlowID);
		String flowViewData=null;
		if(workFlow!=null){
			flowViewData=new String(Base64.decode(workFlow.getFlowViewData()),"UTF-8");
			workFlow.setFlowViewData(flowViewData);
		}

		result.put("workFlow",workFlow);
		return result;
	}

	//根据流程节点Id获取流程信息
	@RequestMapping(value="/getWorkFlowByFlowNodeId")
	@ResponseBody
	public Map<String,Object> getWorkFlowByFlowNodeId(HttpServletRequest request,
                                                      HttpServletResponse response, Integer flowNodeId)throws Exception {
		Map<String,Object> result=new HashMap<String,Object>();
		result.put("data",workFlowService.queryWorkFlowByFlowNodeId(flowNodeId));
		result.put("status", Constant.SUCCESS);
		return result;

	}

	    //获取工作流视图信息
		@RequestMapping(value="/getWorkFlowView")
		@ResponseBody
		public Map<String,Object> getWorkFlowViewData(HttpServletRequest request,
                                                      HttpServletResponse response, String workFlowId)throws Exception {
			Map<String,Object> result=new HashMap<String,Object>();
			Map<String,Object> flowViewData=new HashMap<String,Object>();
			List<Map<String,Object>> flowNodes=flowNodeService.querFlowNodesByWorkFlowID(workFlowId);
			WorkFlow workFlow=workFlowService.queryWorkFlowByID(workFlowId);
			Map<String,Object> states=new HashMap<String,Object>();
			Map<String,Object> paths=new HashMap<String,Object>();

			Map<String,Object> topProps1=new HashMap<String,Object>();
			Map<String,Object> topProps2=new HashMap<String,Object>();
			
			Map<String,Object> topPropsName=new HashMap<String,Object>();
			Map<String,Object> topPropsKey=new HashMap<String,Object>();
			Map<String,Object> topPropsDesc=new HashMap<String,Object>();
			
			topProps2.put("name",topPropsName);
			topProps2.put("key",topPropsKey);
			topProps2.put("desc",topPropsDesc);
			topPropsName.put("value",workFlow.getName());
			topPropsKey.put("value",workFlow.getId());
			topPropsDesc.put("value",workFlow.getDescript());

			topProps1.put("props",topProps2);
			 
			if(flowNodes!=null&&flowNodes.size()>0){
				
				for(Map<String,Object> flowNode:flowNodes){

				/*	if(topPropsName.get("value")==null){
						topPropsName.put("value",flowNode.get("workFlowName"));
					}
					if(topPropsKey.get("value")==null){
						topPropsKey.put("value",flowNode.get("workFlowId"));
					}
					if(topPropsDesc.get("value")==null){
						topPropsDesc.put("value",flowNode.get("workFlowDescript"));
					}*/

					Integer nodeType=flowNode.get("nodeType")==null?null:Integer.parseInt(flowNode.get("nodeType").toString());
					Integer id=flowNode.get("id")==null?null:Integer.parseInt(flowNode.get("id").toString());
					Map<String,Object> viewObj=new HashMap<String,Object>();
					Map<String,Object> attr=new HashMap<String,Object>();
					Map<String,Object> props=new HashMap<String,Object>();
					
					switch(nodeType){
					//开始节点
					case 0:{
						
						viewObj.put("type","start");
						Map<String,Object> topText=new HashMap<String,Object>();
						topText.put("text",flowNode.get("name"));
						viewObj.put("text",topText);
						attr.put("x",flowNode.get("x"));
						attr.put("y",flowNode.get("y"));
						attr.put("width",flowNode.get("width"));
						attr.put("height",flowNode.get("height"));
						viewObj.put("attr",attr);
						Map<String,Object> text=new HashMap<String,Object>();
						text.put("value",flowNode.get("name"));
						props.put("text",text);
						viewObj.put("props",props);
						viewObj.put("nodeID",flowNode.get("id"));
						states.put("rect"+flowNode.get("nodeOrder"),viewObj);
						continue;
					}
					//路径对象
					case 3:{
						
						viewObj.put("from","rect"+flowNode.get("fromRect"));
						viewObj.put("to","rect"+flowNode.get("toRect"));
						Map<String,Object> topText=new HashMap<String,Object>();
						topText.put("text",flowNode.get("name"));
						
						viewObj.put("text",topText);
						
						Map<String,Object> textPos=new HashMap<String,Object>();
						textPos.put("x",flowNode.get("textX"));
						textPos.put("y",flowNode.get("textY"));
						viewObj.put("textPos",textPos);
						
						viewObj.put("dots",new Object[0]);
						
						Map<String,Object> text=new HashMap<String,Object>();
						text.put("value",flowNode.get("name"));
						props.put("text",text);
						viewObj.put("props",props);
						
						viewObj.put("nodeID",flowNode.get("id"));
						paths.put("path"+flowNode.get("nodeOrder"),viewObj);
						continue;
						
					}
					//任务节点
					case 6:{
						viewObj.put("type","task");
						Map<String,Object> topText=new HashMap<String,Object>();
						topText.put("text",flowNode.get("name"));
						viewObj.put("text",topText);
						
						attr.put("x",flowNode.get("x"));
						attr.put("y",flowNode.get("y"));
						attr.put("width",flowNode.get("width"));
						attr.put("height",flowNode.get("height"));
						viewObj.put("attr",attr);
						
						Map<String,Object> text=new HashMap<String,Object>();
						text.put("value",flowNode.get("name"));
						Map<String,Object> performType=new HashMap<String,Object>();
						performType.put("value",flowNode.get("performType")==null?"":flowNode.get("performType"));
						Map<String,Object> taskType=new HashMap<String,Object>();
						taskType.put("value",flowNode.get("taskType")==null?"":flowNode.get("taskType"));
						Map<String,Object> objectScope=new HashMap<String,Object>();
						objectScope.put("value",flowNode.get("objectScope")==null?"":flowNode.get("objectScope"));
						Map<String,Object> orgScope=new HashMap<String,Object>();
						orgScope.put("value",flowNode.get("orgScope")==null?"":flowNode.get("orgScope"));
						Map<String,Object> partInMode=new HashMap<String,Object>();
						partInMode.put("value",flowNode.get("partInMode")==null?"":flowNode.get("partInMode"));
						Map<String,Object> org=new HashMap<String,Object>();
						org.put("value",flowNode.get("orgIds")==null?"":flowNode.get("orgIds"));
						Map<String,Object> role=new HashMap<String,Object>();
						role.put("value",flowNode.get("roleIds")==null?"":flowNode.get("roleIds"));
						Map<String,Object> user=new HashMap<String,Object>();
						user.put("value",flowNode.get("userIDS")==null?"":flowNode.get("userIDS"));
						Map<String,Object> desc=new HashMap<String,Object>();
						desc.put("value",flowNode.get("descript")==null?"":flowNode.get("descript"));
						
						props.put("text",text);
						props.put("performType",performType);
						props.put("taskType",taskType);
						props.put("objectScope",objectScope);
						props.put("orgScope",orgScope);
						props.put("partInMode",partInMode);
						props.put("org",org);
						props.put("role",role);
						props.put("user",user);
						props.put("desc",desc);
						
						viewObj.put("props",props);
						
						viewObj.put("nodeID",flowNode.get("id"));
						states.put("rect"+flowNode.get("nodeOrder"),viewObj);
						continue;
					}
					//结束节点
					case 99:{
						
						viewObj.put("type","end");
						Map<String,Object> topText=new HashMap<String,Object>();
						topText.put("text",flowNode.get("name"));
						viewObj.put("text",topText);
						attr.put("x",flowNode.get("x"));
						attr.put("y",flowNode.get("y"));
						attr.put("width",flowNode.get("width"));
						attr.put("height",flowNode.get("height"));
						viewObj.put("attr",attr);
						
						Map<String,Object> text=new HashMap<String,Object>();
						text.put("value",flowNode.get("name"));
						props.put("text",text);
						viewObj.put("props",props);
						
						viewObj.put("nodeID",flowNode.get("id"));
						states.put("rect"+flowNode.get("nodeOrder"),viewObj);
						continue;
						
					}
					
					}
					
					
					
				}
			}
			
			flowViewData.put("states",states);
			flowViewData.put("paths",paths);
			flowViewData.put("props",topProps1);
			result.put("flowViewData",flowViewData);
			result.put("status","1");
			result.put("msg","获取流程视图信息成功！");
			
			return result;

		}

	//根据当前节点返回下一个流程节点
	@RequestMapping(value="/getNextNode.wdf")
	@ResponseBody
	public Map<String,Object> getNextNode(HttpServletRequest request,
                                          HttpServletResponse response,
                                          String flowNodeID,
                                          String workFlowID)throws Exception {
		List<Map<String,Object>> nextNodes=workFlowService.queryNextFlowNodes(flowNodeID,workFlowID);
		Map<String,Object> nextNode=null;
		if(nextNodes!=null&&nextNodes.size()>0){
			nextNode=nextNodes.get(0);
		}
		return nextNode;
	}


	//获取节点用户
	@RequestMapping(value="/getNodeFlowUsers")
	@ResponseBody
	public Map<String,Object> getNodeFlowUsers(HttpServletRequest request,
                                               HttpServletResponse response,
                                               Integer isCurrent,//是否是获取当前节点参与者信息，如果该参数为1则获取当前flowNodeID节点的参与者信息
                                               PageInfo pageInfo,
                                               String flowNodeId,
                                               String workFlowId,
                                               String orgIds,
                                               String roleIds,
                                               String removeNodeIds,
                                               Integer fillInUserId,
                                               Boolean isRemoveRoleNode,
                                               Integer partType,
                                               String projectIds,
                                               String sectionIds,
											   String siteIds)throws Exception {

		Map<String,Object> result=new HashMap<String,Object>();
		List<Map<String,Object>> treeNodes=new ArrayList<Map<String,Object>>();
		List<Map<String,Object>> nextNodes=new ArrayList<Map<String,Object>>();		//判断是否是项目参与流程
		if(!BaseUtil.isNotEmpty(partType)){
			partType=1;
		}

        if(BaseUtil.isNotEmpty(isCurrent)&&isCurrent==1){
        	nextNodes=workFlowService.queryFlowNodesByID(flowNodeId);
        }else{
        	nextNodes=workFlowService.queryNextFlowNodes(flowNodeId, workFlowId);
        }
		
		
		if(nextNodes!=null&&nextNodes.size()>0){
			for(Map<String,Object> nextNode :nextNodes){

				if(removeNodeIds !=null&&!removeNodeIds.equals("")
						&&nextNode.get("id")!=null
						&& removeNodeIds.indexOf(nextNode.get("id").toString())!=-1
						){
					continue;
				}
				
				int nodeType= Integer.valueOf(nextNode.get("nodeType").toString());
				int orgScopeCount= Integer.valueOf(nextNode.get("orgScope").toString());
				int objectScope= Integer.valueOf(nextNode.get("objectScope").toString());
				User curUser = null;
				curUser = Config.getUser(request);
				//如果业务表单填报用户ID不为空，则以填报用户信息获取相应的节点用户
//				if(BaseUtil.isNotEmpty(fillInUserId)){
//					curUser=userService.queryUserByID(fillInUserId);
//				}
//				else {
//					curUser = Config.getUser(request);
//				}

//				Org userOrg=orgService.queryOrgById(curUser.getOrgIds());

				//如果用户所属机构类型为养护单位，则不根据当前机构范围级别来获取流程节点用户
//				if(userOrg.getOrgType()==0){
//					orgScopeCount=0;
//				}

				String nextNodeID=nextNode.get("id").toString();
				//不能是结束节点
				if(nodeType!= WorkFlowEnum.FlowNodeType.结束.getValue())
				{
					//如果机构范围以当前登录操作用户机构为参照,并且参与对象范围不能指定到用户
					if(orgScopeCount>0&&objectScope!=WorkFlowEnum.ObjectScope.用户.getValue()){

						String scopeOrgIds="";

						//如果机构范围大于一则多线程并行获取指定范围级的机构
						if(orgScopeCount==2){
							//Map<String,Object> condition=new HashMap<String,Object>();
							//获取当前用户的所有机构
							DetachedCriteria condition= DetachedCriteria.forClass(Department.class);
							String[] orgIdsTempArray=curUser.getUserOrgIDS().split(",");
							List<Integer> orgIdsArray=new ArrayList<Integer>();
							for(int i=0;i<orgIdsTempArray.length;i++){
								orgIdsArray.add(Integer.parseInt(orgIdsTempArray[i]));
							}
							condition.add(Property.forName("id").in(orgIdsArray));
							List<Department> userOrgs= departmentService.getByCondition(condition, pageInfo);
							//通过并发线程获取以当前登录用户机构为参照的向上层级数的机构id字符串集合
						     scopeOrgIds=getScopeOrgs(userOrgs,orgScopeCount);
							System.out.println(scopeOrgIds);
							//如果机构范围等于一则直接获取当前登录用户机构为条件
						}else if(orgScopeCount==1){
							scopeOrgIds=curUser.getUserOrgIDS();
						}else if(orgScopeCount==3){
							String orgIdsTemp=curUser.getUserOrgIDS();
							StringBuilder sql = new StringBuilder("SELECT GROUP_CONCAT(DISTINCT d.id) as userOrgs FROM department d WHERE d.pid in ("+orgIdsTemp+") ");
							Map<String,Object> map = workFlowService.getJdbcTemplate().queryForMap(sql.toString());
							if (map!=null){
								scopeOrgIds = (String) map.get("userOrgs");
							}else {
								scopeOrgIds="";
							}
						}

						if(objectScope==WorkFlowEnum.ObjectScope.机构.getValue()){
							result.put("nodeUsers",workFlowService.queryNodeScopeOrgUsers(scopeOrgIds, orgIds, roleIds,projectIds,sectionIds,pageInfo));
						}else if(objectScope==WorkFlowEnum.ObjectScope.角色.getValue()){
							result.put("nodeUsers",workFlowService.queryNodeScopeOrgRoleUsers(nextNodeID,scopeOrgIds, orgIds, roleIds,projectIds,sectionIds,pageInfo));
						}
						//如果参与对象范围是按节点机构
					}else if(objectScope==WorkFlowEnum.ObjectScope.机构.getValue()){
						result.put("nodeUsers",workFlowService.queryNodeOrgUsers(nextNodeID, orgIds, roleIds, projectIds, sectionIds, siteIds,pageInfo));
						//如果参与对象范围是按节点机构角色
					}else if(objectScope==WorkFlowEnum.ObjectScope.角色.getValue()){
						result.put("nodeUsers",workFlowService.queryNodeOrgRoleUsers(nextNodeID, orgIds, roleIds,projectIds,sectionIds,siteIds,pageInfo));
						//如果参与对象范围直接指定到用户
					} else if(objectScope==WorkFlowEnum.ObjectScope.用户.getValue()){
						result.put("nodeUsers",workFlowService.queryNodeUsers(nextNodeID, orgIds, roleIds, projectIds, sectionIds,siteIds,pageInfo));
					}
				}

				//用户机构角色分离形成树状关系
				List<Map<String,Object>> nodeUsers=(List<Map<String,Object>>)result.get("nodeUsers");

				if(isRemoveRoleNode!=null&&isRemoveRoleNode){
					//生成树状关联
					for(Map<String,Object> nodeUser:nodeUsers){
						String orgID= UUID.randomUUID().toString().replaceAll("\\-","");
						Map<String,Object> org=new HashMap<String,Object>();
						Map<String,Object> role=new HashMap<String,Object>();
						Map<String,Object> user=new HashMap<String,Object>();
						if(nodeUser.get("orgID")!=null){
							org.put("id",orgID);
							org.put("realID",nodeUser.get("orgID"));
							org.put("name",nodeUser.get("orgName"));
							org.put("pId",nextNodeID);
							org.put("orderNo",nodeUser.get("orderNo"));
							org.put("nodeType","org");
							//机构去重复
							boolean isRepeat=false;
							String userPID="";
							for(Map<String,Object> node:treeNodes){
								if(node.get("nodeType")!=null&&node.get("nodeType").equals("org")
										&&node.get("realID")!=null&&
										node.get("realID").equals(org.get("realID"))&&
										node.get("pId")!=null&&
										node.get("pId").equals(nextNodeID)
										){
									userPID=node.get("id").toString();
									isRepeat=true;
									break;
								}
							}

							if(!isRepeat){
								treeNodes.add(org);
								userPID=org.get("id").toString();

							}

							String userID= UUID.randomUUID().toString().replaceAll("\\-","");
							user.put("id",userID);
							user.put("realID",nodeUser.get("userID"));
							user.put("name",nodeUser.get("userName"));
							user.put("pId",userPID);
							user.put("orgID",org.get("realID"));
							user.put("flowNodeID",nextNode.get("id"));
							user.put("nodeType","user");
							isRepeat=false;
							for(Map<String,Object> node:treeNodes){
								if(node.get("nodeType")!=null&&node.get("nodeType").equals("user")
										&&node.get("realID")!=null&&
										node.get("realID").equals(user.get("realID"))&&
										node.get("pId")!=null&&
										node.get("pId").equals(userPID)
										){

									userPID=node.get("id").toString();

									isRepeat=true;
									break;
								}
							}
							if(!isRepeat){
								treeNodes.add(user);
							}
						}
					}
				}else{
					//生成树状关联
					for(Map<String,Object> nodeUser:nodeUsers){
						String orgID= UUID.randomUUID().toString().replaceAll("\\-","");
						Map<String,Object> org=new HashMap<String,Object>();
						Map<String,Object> role=new HashMap<String,Object>();
						Map<String,Object> user=new HashMap<String,Object>();
						if(nodeUser.get("orgID")!=null){
							org.put("id",orgID);
							org.put("realID",nodeUser.get("orgID"));
							org.put("name",nodeUser.get("orgName"));
							org.put("pId",nextNodeID);
							org.put("orderNo",nodeUser.get("orderNo"));
							org.put("nodeType","org");
							//机构去重复
							boolean isRepeat=false;
							String rolePID="";
							for(Map<String,Object> node:treeNodes){
								if(node.get("nodeType")!=null&&node.get("nodeType").equals("org")
										&&node.get("realID")!=null&&
										node.get("realID").equals(org.get("realID"))&&
										node.get("pId")!=null&&
										node.get("pId").equals(nextNodeID)){

									rolePID=node.get("id").toString();

									isRepeat=true;
									break;
								}
							}
							if(!isRepeat){
								treeNodes.add(org);
								rolePID=org.get("id").toString();

							}

							if(nodeUser.get("roleID")!=null){
								isRepeat=false;
								String roleID= UUID.randomUUID().toString().replaceAll("\\-","");
								role.put("id",roleID);
								role.put("realID",nodeUser.get("roleID"));
								role.put("name",nodeUser.get("roleName"));
								role.put("pId",rolePID);
								role.put("nodeType","role");
								String userPID="";
								for(Map<String,Object> node:treeNodes){
									if(node.get("nodeType")!=null&&node.get("nodeType").equals("role")
											&&node.get("realID")!=null&&
											node.get("realID").equals(role.get("realID"))&&
											node.get("pId")!=null&&
											node.get("pId").equals(rolePID)
											){

										userPID=node.get("id").toString();

										isRepeat=true;
										break;
									}
								}

								if(!isRepeat){
									treeNodes.add(role);
									userPID=role.get("id").toString();

								}

								String userID= UUID.randomUUID().toString().replaceAll("\\-","");
								user.put("id",userID);
								user.put("realID",nodeUser.get("userID"));
								user.put("name",nodeUser.get("userName"));
								user.put("pId",userPID);
								user.put("orgID",org.get("realID"));
								user.put("roleID",role.get("realID"));
								user.put("flowNodeID",nextNode.get("id"));
								user.put("nodeType","user");
								isRepeat=false;
								for(Map<String,Object> node:treeNodes){
									if(node.get("nodeType")!=null&&node.get("nodeType").equals("user")
											&&node.get("realID")!=null&&
											node.get("realID").equals(user.get("realID"))&&
											node.get("pId")!=null&&
											node.get("pId").equals(rolePID)
											){

										userPID=node.get("id").toString();

										isRepeat=true;
										break;
									}
								}
								if(!isRepeat){
									treeNodes.add(user);
								}

							}

						}
					}
				}

				//添加流程节点信息
				nextNode.put("nodeType","nodeFlow");
				treeNodes.add(nextNode);

			}
			result.put("status","1");
			result.put("msg","获取节点用户信息成功！");
			result.put("pageInfo",pageInfo);
			Collections.sort(treeNodes, new ComMapObjCompatator("orderNo"));
			result.put("data",treeNodes);
		}
		return result;
	}

	
	//递归获取审核机构范围
	public Department recurFindPorg(Integer pid, int index) throws Exception {
		Department org = workFlowService.queryOrgByID(pid);
		if (org!=null&&org.getParent().getId()!= null && !org.getParent().getId().equals("") && !org.getParent().getId().equals("00") && index != 0) {
			index--;
			org = recurFindPorg(org.getParent().getId(), index--);
		}
		return org;
	}

	//同步获取父节点机构对象类
	class ScopeOrg {
		private int data;// 共享数据
		private List<Department> orgs;

		public ScopeOrg(){
			orgs=new ArrayList<Department>();
		}
		public List<Department> getOrgs() {
			return orgs;
		}
		public void setOrgs(List<Department> orgs) {
			this.orgs = orgs;
		}
		private ReadWriteLock rwl = new ReentrantReadWriteLock();

		public void set(Integer pOrgID, int scopeCount) {
			rwl.writeLock().lock();// 取到写锁
			try {
				System.out.println(Thread.currentThread().getName() + "获取当前节点登录用户向上："+scopeCount+"级机构");
				try {
					Thread.sleep(20);
					Department org=recurFindPorg(pOrgID,scopeCount);
  				if(org!=null){
						orgs.add(org);
						System.out.println(Thread.currentThread().getName() + "找到机构：" +org.getName());
					}
				} catch (Exception e) {
					e.printStackTrace();
				}
			} finally {
				rwl.writeLock().unlock();// 释放写锁
			}
		}
			/*public void get() {
				rwl.readLock().lock();// 取到读锁
				try {
					System.out.println(Thread.currentThread().getName() + "准备读取数据");
					try {
						Thread.sleep(20);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
					System.out.println(Thread.currentThread().getName() + "读取" + this.data);
				} finally {
					rwl.readLock().unlock();// 释放读锁
				}
			}*/
	}

	public String getScopeOrgs(List<Department> userOrgs, int orgScopeCount)throws Exception {
		final ScopeOrg scopeOrg =new ScopeOrg();
		//生产监听线程执行完成对象
		final CountDownLatch latch=new CountDownLatch(userOrgs.size());

		for(int i=0;i<userOrgs.size();i++){
			final Department userOrg=userOrgs.get(i);
			final int index=orgScopeCount;
			new Thread(){
				@Override
				public void run(){
					if(userOrg.getParent()!=null)
					scopeOrg.set(userOrg.getParent().getId(),index-2);
					//线程执行完成计数
					latch.countDown();
				}
			}.start();

		}
		//等待所有线程完成向上机构查询工作
		latch.await();
		List<Department> scopeOrgs=scopeOrg.getOrgs();
		StringBuffer scopeOrgIDS=new StringBuffer();
		//把找到的当前用户所有机构向上的机构，组合成ID字符串集合
		for(int i=0;i<scopeOrgs.size();i++){
			Department org=scopeOrgs.get(i);
			if(i+1==scopeOrgs.size()){
				scopeOrgIDS.append(org.getId());
				break;
			}
			scopeOrgIDS.append(org.getId()+",");
		}
		return scopeOrgIDS.toString();
	}

	//获取所有任务流程
	@RequestMapping(value="/listAllTaskFlows.wdf")
	@ResponseBody
	public Map<String,Object> listAllWorkFlows(HttpServletRequest request,
                                               HttpServletResponse response)throws Exception {
		Map<String,Object> result=new HashMap<String,Object>();
		result.put("nodes",workFlowService.queryWorkFlow());
		result.put("state",1);
		return result;
	}

	/**
	 * 获取任务流程开始节点和初始节点
	 * @param request
	 * @param response
	 * @param workFlowID
	 * @return
	 * @throws Exception
	 */
	@RequestMapping(value="/getBeginAndInitNodes.wdf")
	@ResponseBody
	public Map<String,Object> getBeginAndInitNodes(HttpServletRequest request,
                                                   HttpServletResponse response, String workFlowID)throws Exception {
		Map<String,Object> result=new HashMap<String,Object>();
		Map<String,Map<String,Object>> workFlowConfs= Config.getWorkFlowConf();
		Map<String,Object> beginNode=workFlowService.queryBeginNode(workFlowID);

		Map<String,Object> initNode=new HashMap<String,Object>();
		List<Map<String,Object>> nextNodes=workFlowService.queryNextFlowNodes(beginNode.get("id").toString(),workFlowID);
		if(nextNodes!=null&&nextNodes.size()>0){
			initNode=nextNodes.get(0);
			Map<String,Object> workFlowConf=workFlowConfs.get(initNode.get("workFlowId"));
			Map<String,Object> nodeConf=(Map<String,Object>)workFlowConf.get(initNode.get("id"));
			initNode.put("formView",nodeConf.get("formView"));
		}
		result.put("beginNode",beginNode);
		result.put("initNode",initNode);
		result.put("state",1);
		return result;
	}


	@RequestMapping(value="/listTaskLogs.wdf")
	@ResponseBody
	public Map<String,Object> listMyTaskLogs(HttpServletRequest request,
                                             HttpServletResponse response, PageInfo pageInfo,
                                             Integer id, String flowNodeName,
                                             String forwarderName, String processerName,
                                             String SendBeginTime, String SendEndTime,
                                             String procBeginTime, String procEndTime, Integer status)throws Exception {
		Map<String,Object> result=new HashMap<String,Object>();
		Map<String,String> condition=new HashMap<String,String>();
		if(id!=null){
			condition.put("id","="+id);
		}
		if(flowNodeName!=null&&!flowNodeName.equals("")){
			condition.put("flowNode.name","LIKE '%"+flowNodeName+"%'");
		}
		if(forwarderName!=null&&!forwarderName.equals("")){
			condition.put("forwarder.name","LIKE '%"+forwarderName+"%'");
		}
		if(processerName!=null&&!processerName.equals("")){
			condition.put("processer.name","LIKE '%"+processerName+"%'");
		}
		if(SendBeginTime!=null&&!SendBeginTime.equals("")){
			condition.put("createTime",">='"+SendBeginTime+"'");
		}
		if(SendEndTime!=null&&!SendEndTime.equals("")){
			condition.put("createTime","<='"+SendEndTime+"'");
		}
		if(procBeginTime!=null&&!procBeginTime.equals("")){
			condition.put("procTime",">='"+procBeginTime+"'");
		}
		if(procEndTime!=null&&!procEndTime.equals("")){
			condition.put("procTime","<='"+procEndTime+"'");
		}
		if(status!=null){
			condition.put("status","="+status);
		}
		List<TaskLog> taskLogs=taskLogService.queryTaskLogs(condition, pageInfo);
		if(taskLogs!=null){
			Map<String,Map<String,Object>> workFlowConfs= Config.getWorkFlowConf();
			for(TaskLog taskLog:taskLogs){
				Map<String,Object> workFlowConf=workFlowConfs.get(taskLog.getFlowNode().getWorkFlowId());
				Map<String,Object> flowNodeConf=(Map<String,Object>)workFlowConf.get(taskLog.getFlowNode().getId());
				taskLog.getFlowNode().setFormView(flowNodeConf.get("formView").toString());
			}
		}
		result.put("taskLogs",taskLogs);
		result.put("pageInfo",pageInfo);
		return result;
	}


	@RequestMapping(value="/getTaskLog.wdf")
	@ResponseBody
	public Map<String,Object> getTaskLog(HttpServletRequest request,
                                         HttpServletResponse response, Integer id)throws Exception {

		Map<String,Object> result=new HashMap<String,Object>();
		Map<String,String> condition=new HashMap<String,String>();
		condition.put("id","="+id);

		result.put("taskLog",taskLogService.queryTaskLog(condition));
		result.put("state",0);
		return result;
	}


	/**
	 * 转交撤回
	 * @param request
	 * @param response
	 * @return
	 * @throws Exception
	 */
	@RequestMapping(value="/recall")
	@ResponseBody
	public Map<String,Object> recall(HttpServletRequest request,
                                     HttpServletResponse response,
                                     Integer tID,
                                     Integer bID)throws Exception {

		Map<String,Object> result=new HashMap<String,Object>();
		TaskLog taskLog=taskLogService.queryTaskLog(tID);
		List<Map<String,Object>> nextNodes=workFlowService.queryNextFlowNodes(taskLog.getFlowNode().getId().toString(),taskLog.getFlowNode().getWorkFlowId());
		result=taskLogService.updateTaskLogForRecall(bID, tID,taskLog.getFlowNode(), nextNodes);

		return result;
	}

	/**
	 * @author wonderful 20190730 1320 根据id获取工作流节点对象，用于远程方法调用。
	 * @param flowNodeId
	 * @return
	 * @throws Exception
	 */
	@RequestMapping(value="/getWorkFlowByFlowNodeId_RMI")
	@ResponseBody
	public Result getWorkFlowByFlowNodeId(String flowNodeId)throws Exception {
		Map<String,Object> result=new HashMap<String,Object>();
		return new Result(Constant.SUCCESS,"获取节点信息成功",workFlowService.queryFlowNodeByID(flowNodeId));
	}


	@RequestMapping(value="/listWorkProgress.wdf")
	@ResponseBody
	@Comment("获取业务进度列表")
	public Result listWorkProgress(String workFlowId, Integer bId, Integer order, PageInfo pageInfo) throws Exception {
		logger.info("listWorkProgress workFlowId="+workFlowId+",bId="+bId);
		//Result result = impBusinessRMI.getWorkProgress(workFlowId, bId, order, pageInfo);
		List<Map<String, Object>> data = workFlowService.getWorkProgress(workFlowId, bId, order, pageInfo);
		return new Result(Constant.SUCCESS, "获取业务进度列表成功", data, pageInfo);
	}

	@RequestMapping(value="/listWorkFlowLogs.wdf")
	@ResponseBody
	@Comment("获取业务流程操作记录列表")
	public Result listWorkFlowLogs(HttpServletRequest request,String workFlowId, Integer bId, PageInfo pageInfo) throws Exception {
		//Result result = impBusinessRMI.getWorkFlowLogs(workFlowId, bId,pageInfo);
		List<Map<String, Object>> data = workFlowService.getWorkFlowLogs(request, workFlowId, bId, pageInfo);
		return new Result(Constant.SUCCESS, "获取业务流程操作记录列表成功", data, pageInfo);
	}

	/**
	 * 根据多个节点id获取工作流节点对象，用于远程方法调用。
	 * @author Pyj 20191024
	 * @param flowNodeIds
	 * @return
	 * @throws Exception
	 */
	@RequestMapping(value="/queryFlowNodesByID")
	@ResponseBody
	public Result queryFlowNodesByID(String flowNodeIds)throws Exception {
		return new Result(Constant.SUCCESS,"获取节点信息成功",workFlowService.queryFlowNodesByID(flowNodeIds));
	}


}
